#include <iostream>
#include <ctime>
#include "interfaz.h"
#include "graficos.h"
#include "cola_piezas.h"
#include "marcador.h"
#include "imagen.h"

using namespace std;
using namespace graficos;

int main(int argc,char* argv[]){
//*****************Controlo argumentos**********************************	
	if(argc!=2 && argc!=3){ 
		cerr<<"Numero de argumentos invalido"<<endl;
		cout<<"Sintaxis: bin/tetris <fichero configuración> [<nombre jugador>]"<<endl;
		exit(1);
	}
//*****************************************************************************	
	
	Interfaz inter(argv[1]);	
	srand(inter.Semilla());	
	CronometroInicio();
	
	CrearVentana(inter.AnchoTablero()+inter.AnchoCola()+inter.AnchoTitulo()+2*inter.PosXTablero(),inter.AltoTablero()+2*inter.PosYTablero(),"Tetris");
	Acumulador acu=inter.Acu();
	VectorPiezas vp=inter.Vector();
	ColaPiezas c(inter.PosXCola(),inter.PosYCola(),inter.AnchoCola(),inter.AltoCola(),inter.MarcoCola(),inter.ColorBordeCola(),inter.ColorFondoCola(),vp,inter.PiezasCola());	
		
//************* Meto las imagenes en un vector de imagenes ****************************************
	Imagen im[inter.NumImagenes()]; //Vector de imagenes 
	char** todas_img=inter.Imagenes();
	for(int i=0;i<inter.NumImagenes();i++){
		string aux;
		aux.append(inter.DirImagenes());
		aux.insert(aux.size(),"/");
		aux.insert(aux.size(),todas_img[i]);			
		im[i].LeerImagen(aux.c_str());		
	}	
	
//****************** Declaro e inicializo vbles ***************************************************
	int num_lineas=0,num_nivel=0,num_piezas=0; //variables para marcadores
	char* aux_texto;
	string texto_nivel,texto_lineas,texto_piezas,texto_estado; //texto de marcadores
		
	int posx;
	int posy;
	int aleatorio;
	long int tiempo1=0,tiempo2=inter.TiempoEspera();//Para controlar el tiempo

	
//**************************Marcadores**************************************************************	
	
	Marcador titulo(inter.PosXTitulo(),inter.PosYTitulo() ,inter.AnchoTitulo(),inter.AltoTitulo(),inter.MarcoTitulo(),inter.ColorFondoTitulo(),inter.ColorBordeTitulo());	
	titulo.SetLetra(inter.Titulo(),inter.FuenteTitulo(),inter.TamTitulo(),inter.EstiloTitulo(),1,inter.ColorTitulo() );
	
	sprintf(aux_texto,"%d",num_nivel);	
	texto_nivel="Nivel: ";
	texto_nivel.insert(texto_nivel.size(),aux_texto);
	Marcador nivel(inter.PosXNivel(),inter.PosYNivel() ,inter.AnchoNivel(),inter.AltoNivel(),inter.MarcoNivel(),inter.ColorFondoNivel(),inter.ColorBordeNivel());	
	nivel.SetLetra((char*)(texto_nivel.c_str()),inter.FuenteNivel(),inter.TamNivel(),inter.EstiloNivel(),0,inter.ColorNivel() );
	
	sprintf(aux_texto,"%d",num_lineas);
	texto_lineas="Lineas: ";
	texto_lineas.insert(texto_lineas.size(),aux_texto);
	Marcador lineas(inter.PosXLineas(),inter.PosYLineas() ,inter.AnchoLineas(),inter.AltoLineas(),inter.MarcoLineas(),inter.ColorFondoLineas(),inter.ColorBordeLineas());	
	lineas.SetLetra((char*)(texto_lineas.c_str()),inter.FuenteLineas(),inter.TamLineas(),inter.EstiloLineas(),0,inter.ColorLineas() );
	
	sprintf(aux_texto,"%d",num_piezas);
	texto_piezas="Piezas: ";
	texto_piezas.insert(texto_piezas.size(),aux_texto);
	Marcador piezas(inter.PosXPiezas(),inter.PosYPiezas() ,inter.AnchoPiezas(),inter.AltoPiezas(),inter.MarcoPiezas(),inter.ColorFondoPiezas(),inter.ColorBordePiezas());	
	piezas.SetLetra((char*)(texto_piezas.c_str()),inter.FuentePiezas(),inter.TamPiezas(),inter.EstiloPiezas(),0,inter.ColorPiezas() );
	
	
	texto_estado="Jugando...";
	Marcador estado(inter.PosXEstado(),inter.PosYEstado() ,inter.AnchoEstado(),inter.AltoEstado(),inter.MarcoEstado(),inter.ColorFondoEstado(),inter.ColorBordeEstado());	
	estado.SetLetra((char*)(texto_estado.c_str()),inter.FuenteEstado(),inter.TamEstado(),inter.EstiloEstado(),1,inter.ColorEstado() );
			
	int cont=0,cont2=0;//me sirve para mirar numero lineas
	while(!acu.Pierdes()){
//**************************Cojo una pieza de la cola e inserto otra******************************************			
		Pieza pieza;
		pieza=c[0];		
		num_piezas++;
		aleatorio=(rand()%inter.NumPiezas());
		c.InsertarPieza(vp[aleatorio]);
		
//*****************Inicializo posiciones y booleanos ***************************************
		posx=(acu.Columnas()-pieza.Columnas())/2;
		posy=0;
		bool toca_ficha=false;	
		bool toca_suelo=false;
		

//**************************Miro lineas y nivel**********************************
		cont2=acu.HayLineas();
		cont=cont+cont2;
		
		if(inter.LineasNivel()<=cont){
			num_nivel++;
			cont=cont-inter.LineasNivel();		
		}
		num_lineas=num_lineas+cont2; 	
//***********************************************************************************		
		while(!toca_suelo && !toca_ficha){
			
			bool abajo=false;
			bool izd=false;
			bool dcha=false;
			bool rota_dcha=false;
			bool rota_izda=false;
			bool toca_izda=false;
			bool toca_dcha=false;
//*********************************Compruebo si toco suelo o ficha por abajo**********************************************
			if(posy==acu.Filas()-pieza.Filas()) toca_suelo=true;
			if(!toca_suelo){
				for(int i=0;i<pieza.Filas();i++){
					for(int j=0;j<pieza.Columnas();j++){
						if( (acu.Get(posy+i+1,posx+j)!=0) && (pieza.Get(i,j)!=0)  ) toca_ficha=true;
					} 
				
				} 	
				
			}
					
			
//*******************************Copio ficha a tablero**********************************
			for(int i=0;i<pieza.Filas();i++){
				for(int j=0;j<pieza.Columnas();j++){					
						if(acu.Get(posy+i,posx+j)==0) acu.Set(posy+i,posx+j,pieza.Get(i,j));
				}
			}

			
//******************* Pinto todo **********************************************************************		
			DesactivarDibujo();
			LimpiarVentana();
			c.Pinta(im,inter.NumImagenes());
			
			acu.Pinta(im,inter.NumImagenes());
			
			titulo.Pinta();
			
			sprintf(aux_texto,"%d",num_nivel);
			texto_nivel="Nivel: ";
			texto_nivel.insert(texto_nivel.size(),aux_texto);
			nivel.SetLetra((char*)(texto_nivel.c_str()),inter.FuenteNivel(),inter.TamNivel(),inter.EstiloNivel(),0,inter.ColorNivel() );
			nivel.Pinta();
			
			sprintf(aux_texto,"%d",num_lineas);
			texto_lineas="Lineas: ";
			texto_lineas.insert(texto_lineas.size(),aux_texto);
			lineas.SetLetra((char*)(texto_lineas.c_str()),inter.FuenteLineas(),inter.TamLineas(),inter.EstiloLineas(),0,inter.ColorLineas() );
			lineas.Pinta();
			
			
			sprintf(aux_texto,"%d",num_piezas);
			texto_piezas="Piezas: ";
			texto_piezas.insert(texto_piezas.size(),aux_texto);
			piezas.SetLetra((char*)(texto_piezas.c_str()),inter.FuentePiezas(),inter.TamPiezas(),inter.EstiloPiezas(),0,inter.ColorPiezas() );
			piezas.Pinta();
			
			estado.Pinta();
			ActivarDibujo();
			
			
			Esperar(5);
			tiempo1=CronometroValor();	
			
//****************************** Borro ficha y bajo ***********************************************************			
			if(!toca_ficha && !toca_suelo){

				if(posy>acu.Filas()-1) posy=acu.Filas()-1;
				for(int i=0;i<pieza.Filas();i++){
					for(int j=0;j<pieza.Columnas();j++){
						if(pieza.Get(i,j)!=0 ) acu.Set(posy+i,posx+j,0);
					}
				}
				if(tiempo1>=tiempo2){
					posy++;				
					tiempo2=tiempo1+(inter.TiempoEspera()/(1+(num_nivel/4)));
				}
			}	
			
//***************************Miro si hay una tecla pulsada*****************************************************			
			TTecla te; 
			te=QueTeclaHayPulsada();
			if(te==SDLK_w) rota_dcha=true;
			if(te==SDLK_q) rota_izda=true;
			if(te==SDLK_RIGHT) dcha=true;	
			if(te==SDLK_LEFT) izd=true;
			if(te==SDLK_DOWN) abajo=true;
			
						 
			//Miro si puedo mover ficha a izda
		
				for(int i=0;i<pieza.Filas();i++){
					for(int j=0;j<pieza.Columnas();j++){
						if(pieza.Get(i,j)!=0 && acu.Get(posy+i,posx+j-1)!=0) toca_izda=true;		
				
					}
			
				}
		
			
			//Miro si puedo mover ficha a dcha
			
				for(int i=0;i<pieza.Filas();i++){
					for(int j=0;j<pieza.Columnas();j++){
						if(pieza.Get(i,j)!=0 && acu.Get(posy+i,posx+j+1)!=0) toca_dcha=true;		
				
					}
			
				}
	

			
			
			if(dcha && !toca_dcha && (posx<(acu.Columnas()-pieza.Columnas())))posx++; 
			if(izd && !toca_izda && posx>0) posx--;	
			if(rota_dcha){
				posx=posx+(pieza.Columnas()-pieza.Filas());
				Pieza pieza_aux=pieza;
				pieza_aux.RotaDcha();	
				
				for(int i=0;i<pieza_aux.Filas();i++){
					for(int j=0;j<pieza_aux.Columnas();j++){
						if(pieza_aux.Get(i,j)!=0 && acu.Get(posy+i,posx+j)!=0) rota_dcha=false;		
				
					}
			
				}
				if(rota_dcha && posx>=0 && (posx<=(acu.Columnas()-pieza_aux.Columnas()))){
					pieza.RotaDcha();
					
				}
				else posx=posx-(pieza.Columnas()-pieza.Filas());
				
			}
			if(rota_izda){ 
				posx=posx+(pieza.Columnas()-pieza.Filas());
				Pieza pieza_aux=pieza;
				pieza_aux.RotaIzda();	
				for(int i=0;i<pieza_aux.Filas();i++){
					for(int j=0;j<pieza_aux.Columnas();j++){
						if(pieza_aux.Get(i,j)!=0 && acu.Get(posy+i,posx+j)!=0) rota_izda=false;		
				
					}
			
				}
				if(rota_izda && posx>=0 && (posx<=(acu.Columnas()-pieza_aux.Columnas()))){ 
					pieza.RotaIzda();
					
				}
				else posx=posx-(pieza.Columnas()-pieza.Filas());
								
			}
			if(abajo && posy<(acu.Filas()-pieza.Filas())){
				bool toco=false;
				for(int i=0;i<pieza.Filas();i++){
					for(int j=0;j<pieza.Columnas();j++){
						if( (acu.Get(posy+i+1,posx+j)!=0) && (pieza.Get(i,j)!=0)  ) toco=true;
					} 
				
				} 	
				if(!toco) posy++;
				if(posy>acu.Filas()-1) posy=acu.Filas()-1;			
			}
		
		}	
				
	}	
	
//**************** Pierdes***************************************************+
	DesactivarDibujo();
	LimpiarVentana();
	
	c.Pinta(im,inter.NumImagenes());
	acu.Pinta(im,inter.NumImagenes());
	titulo.Pinta();
	nivel.Pinta();
	lineas.Pinta();
	piezas.Pinta();
	
	texto_estado="Has Perdido";	
	estado.SetLetra((char*)(texto_estado.c_str()),inter.FuenteEstado(),inter.TamEstado(),inter.EstiloEstado(),1,inter.ColorEstado() );
	estado.Pinta();	
	ActivarDibujo();	
	ObtenerTecla();	

}	
